#include "PCF8563.h"
#include "i2c_communication_driver.h"
uint8_t rtc_I2C_Start(void)                  // I2C发送START条件
{
    i2c_Start();
    return 0;
}
uint8_t rtc_I2C_SendAddr(uint8_t addr)       // 发送I2C从机地址（含读/写位）
{
    i2c_SendByte(addr);
    	/* 第3步：等待ACK */
	if (i2c_WaitAck() != 0)
	{
		return 1;
	}
    return 0;
}
uint8_t rtc_I2C_SendData(uint8_t data)       // 发送1字节数据
{
    i2c_SendByte(data);
	if (i2c_WaitAck() != 0)
	{
		return 1;
	}
    return 0;
}
uint8_t rtc_I2C_ReadData(uint8_t *pdata, uint8_t ack) // 读1字节（ack=1需应答，0=无应答）
{
    uint8_t data=0;
    data=i2c_ReadByte();
    if (ack == 1) {
        i2c_Ack();
    }
    else {
        i2c_NAck();
    }
    return data;
}
void rtc_I2C_Stop(void)                      // I2C发送STOP条件
{
    i2c_Stop();
}
/**
 * @brief  PCF8563初始化
 * @details 步骤：1. 冻结时间（置STOP位）；2. 清除VL位（时间无效标记）；3. 释放时间（清STOP位）
 */
uint8_t PCF8563_Init(void) 
{
    uint8_t ctrl_status1 = 0;
    // 步骤1：读取Control_status1（00h），准备置STOP位
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    // 切换为读模式
    if (rtc_I2C_Start() != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendAddr(PCF8563_ADDR_READ) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_ReadData(&ctrl_status1, 0); // 读1字节，无应答
    rtc_I2C_Stop();

    // 步骤2：置STOP位（冻结时间，文档8.10）
    ctrl_status1 |= PCF8563_STOP_BIT;
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(ctrl_status1) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_Stop();

    // 步骤3：清除VL位（文档8.4.1：VL=1表示时间无效，需写0清除）
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_VL_SECONDS) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(0x00) != 0) { rtc_I2C_Stop(); return 1; } // VL位清0，秒初始化为0
    rtc_I2C_Stop();

    // 步骤4：释放STOP位（恢复时间计数，文档8.10）
    ctrl_status1 &= ~PCF8563_STOP_BIT;
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(ctrl_status1) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_Stop();

    return 0;
}

/**
 * @brief  BCD码转十进制
 */
uint8_t BCD_to_Dec(uint8_t bcd_val) {
    return ((bcd_val >> 4) * 10) + (bcd_val & 0x0F);
}

/**
 * @brief  十进制转BCD码
 */
uint8_t Dec_to_BCD(uint8_t dec_val) {
    if (dec_val > 99) return 0x99; // 限制最大值（时间参数不会超过99）
    return (((dec_val / 10) << 4) | (dec_val % 10));
}

/**
 * @brief  检查时间合法性（避免写入无效时间）
 */
static uint8_t PCF8563_CheckTime(PCF8563_TimeTypeDef *pTime) {
    if (pTime->seconds > 59) return 1;
    if (pTime->minutes > 59) return 1;
    if (pTime->hours > 23) return 1;
    if (pTime->days < 1 || pTime->days > 31) return 1;
    if (pTime->weekdays > 6) return 1;
    if (pTime->months < 1 || pTime->months > 12) return 1;
    if (pTime->years > 99) return 1;
    return 0; // 时间合法
}

/**
 * @brief  写入时间到PCF8563（一次性写02h~08h，文档8.5要求）
 */
uint8_t PCF8563_WriteTime(PCF8563_TimeTypeDef *pTime) {
    uint8_t ctrl_status1 = 0;
    uint8_t bcd_buf[7]; // 存储BCD格式的秒、分、时、日、星期、月、年

    // 1. 检查时间合法性
    if (PCF8563_CheckTime(pTime) != 0) return 1;

    // 2. 十进制转BCD，填充缓冲区（对应02h~08h寄存器）
    bcd_buf[0] = Dec_to_BCD(pTime->seconds) & ~PCF8563_VL_BIT; // 清VL位
    bcd_buf[1] = Dec_to_BCD(pTime->minutes);
    bcd_buf[2] = Dec_to_BCD(pTime->hours);
    bcd_buf[3] = Dec_to_BCD(pTime->days);
    bcd_buf[4] = Dec_to_BCD(pTime->weekdays);
    // 月+世纪：bit7=世纪位，bit4~0=月（BCD）
    bcd_buf[5] = (pTime->century ? PCF8563_CENTURY_BIT : 0) | Dec_to_BCD(pTime->months);
    bcd_buf[6] = Dec_to_BCD(pTime->years);

    // 3. 冻结时间（置STOP位，文档8.10）
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_ReadData(&ctrl_status1, 0); // 读当前Control_status1
    rtc_I2C_Stop();

    ctrl_status1 |= PCF8563_STOP_BIT;
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(ctrl_status1) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_Stop();

    // 4. 一次性写入02h~08h寄存器（文档8.5：必须单次完整写）
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_VL_SECONDS) != 0) { rtc_I2C_Stop(); return 1; } // 指针指向02h

    // 依次发送秒→年的BCD数据
    for (uint8_t i = 0; i < 7; i++) {
        if (rtc_I2C_SendData(bcd_buf[i]) != 0) { rtc_I2C_Stop(); return 1; }
    }
    rtc_I2C_Stop();

    // 5. 释放时间（清STOP位，恢复计数）
    ctrl_status1 &= ~PCF8563_STOP_BIT;
    if (rtc_I2C_Start() != 0) return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(PCF8563_CTRL_STATUS1) != 0) { rtc_I2C_Stop(); return 1; }
    if (rtc_I2C_SendData(ctrl_status1) != 0) { rtc_I2C_Stop(); return 1; }
    rtc_I2C_Stop();

    return 0;
}

/**
 * @brief  从PCF8563读取时间（一次性读02h~08h，文档8.5推荐流程）
 */
uint8_t PCF8563_ReadTime(PCF8563_TimeTypeDef *pTime) 
{
    uint8_t bcd_buf[7]; // 存储读取的BCD数据（02h~08h）

    // 1. 发送START→写从机地址→设置寄存器指针为02h（VL_seconds）
    if (rtc_I2C_Start() != 0) 
        return 1;
    if (rtc_I2C_SendAddr(PCF8563_ADDR_WRITE) != 0) 
    { 
        rtc_I2C_Stop();
        return 1; 
    }
    if (rtc_I2C_SendData(PCF8563_VL_SECONDS) != 0)
    {
         rtc_I2C_Stop(); 
         return 1; 
    }

    // 2. RESTART→读从机地址→依次读取7个寄存器（秒→年）
    if (rtc_I2C_Start() != 0) 
    { 
        rtc_I2C_Stop(); 
        return 1; 
    }
    if (rtc_I2C_SendAddr(PCF8563_ADDR_READ) != 0)
    { 
        rtc_I2C_Stop(); 
        return 1; 
    }

    // 读前6字节：需应答（ack=1）；读第7字节：无应答（ack=0）
    for (uint8_t i = 0; i < 4; i++) 
    {
        if (rtc_I2C_ReadData(&bcd_buf[i], 1) != 0) 
        { 
            rtc_I2C_Stop(); 
            return 1; 
        }
    }
    if (rtc_I2C_ReadData(&bcd_buf[4], 0) != 0) 
    {
         rtc_I2C_Stop();
         return 1; 
    }
    rtc_I2C_Stop();

    // 3. BCD转十进制，填充时间结构体
    pTime->seconds = BCD_to_Dec(bcd_buf[0] & ~PCF8563_VL_BIT); // 屏蔽VL位
    pTime->minutes = BCD_to_Dec(bcd_buf[1]);
    pTime->hours = BCD_to_Dec(bcd_buf[2]);
    pTime->days = BCD_to_Dec(bcd_buf[3]);
    pTime->weekdays = BCD_to_Dec(bcd_buf[4]);
    // 提取世纪位（bit7）和月（bit4~0）
//    pTime->century = (bcd_buf[5] & PCF8563_CENTURY_BIT) ? 1 : 0;
//    pTime->months = BCD_to_Dec(bcd_buf[5] & 0x1F); // 月仅占bit4~0（0x1F=00011111）
//    pTime->years = BCD_to_Dec(bcd_buf[6]);

    // 4. 检查VL位（判断时间是否有效，文档8.4.1）
    pTime->time_valid = (bcd_buf[0] & PCF8563_VL_BIT) ? 1 : 0;

    return 0;
}

